/* chimaera_file-table.c : store the access condition of files
 *
 * ====================================================================
 * Copyright (c) 2008-2009 Chimaera team.  All rights reserved.
 *
 *
 * @author kkndyu
 * @mail kkndyu@gmail.com
 * ====================================================================
 */

#include "bdb_compat.h"
#include "svn_fs.h"
#include "svn_pools.h"
#include "../fs.h"
#include "../err.h"
#include "../util/skel.h"
#include "../util/fs_skels.h"
#include "../../libsvn_fs/fs-loader.h"
#include "bdb-err.h"
#include "dbt.h"
#include "rev-table.h"
#include "../trail.h"

#include "svn_private_config.h"
#include "private/svn_fs_util.h"

#include "chimaera_file-table.h"


/* Opening/creating the 'chimaera_file' table.  */

int svn_fs_bdb__open_chimaera_file_table(DB **chimaerafile_p,
                                     DB_ENV *env,
                                     svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *chimaera_file;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&chimaera_file, env, 0));

  //chimaera_file->set_flags(chimaera_file,DB_DUP);

  BDB_ERR((chimaera_file->open)(SVN_BDB_OPEN_PARAMS(chimaera_file, NULL),
								"chimaera_file", 0, DB_BTREE,
								open_flags, 0666));

  *chimaerafile_p = chimaera_file;
  return 0;
}



/* Storing and retrieving filesystem revisions.  */


svn_error_t *
svn_fs_bdb__get_chimaera_file(chimaerafile_t **chimaerafile_p,
					char *path,  svn_fs_t *fs, apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  int db_err;
  DBT key, value;
  char *dup_path;

  if (path!=NULL)
  {
	  chimaerafile_t * cf = apr_palloc(pool,sizeof(*cf));

	  svn_fs_base__str_to_dbt(&key, path),
      svn_fs_base__result_dbt(&value),
		

	  db_err = bfd->chimaera_file->get(bfd->chimaera_file,NULL,
								&key, &value, 0);
	  svn_fs_base__track_dbt(&value, pool);

	  if (db_err == DB_NOTFOUND)
		  return svn_error_create(9999,NULL,_("path error!"));

	  /* add value to chimaerafile_t */
	  memcpy(&(cf->project),value.data,value.size);

	  /* add key to chimaerafile_t */
	  dup_path = apr_pcalloc(pool,strlen(path)+1);
	  memcpy(dup_path,path,strlen(path));
	  cf->Path = dup_path;

	  *chimaerafile_p = cf;

  }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_bdb__put_chimaera_file(chimaerafile_t *chimaerafile_p,
							  svn_fs_t *fs, DB_TXN *txn,apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBT key, value;
  void * value_pointer;

  svn_fs_base__set_dbt(&key, chimaerafile_p->Path, strlen(chimaerafile_p->Path));

  /* move the pointer to point at the value section in the structure*/
  value_pointer = &(chimaerafile_p->project);

  svn_fs_base__set_dbt(&value, value_pointer, CHIMAERA_FILE_VALUE_LENGTH);

  SVN_ERR(BDB_WRAP(fs, _("storing message index"),
	  bfd->chimaera_file->put(bfd->chimaera_file, txn,
	  &key, &value, 0)));
  
  return SVN_NO_ERROR;
}

/* need */
svn_error_t *
svn_fs_bdb__del_chimaera_file(char *url,
							  svn_revnum_t id,
							  svn_fs_t *fs,
							  DB_TXN *txn,
							  apr_pool_t *pool)
{
	int ret;
	DBC *cursor = 0;
	DBT key, value;
	base_fs_data_t *bfd = fs->fsap_data;

	chimaerafile_t *cfile = apr_pcalloc(pool,sizeof(*cfile));

	bfd->chimaera_file->cursor(
		bfd->chimaera_file,
		txn,&cursor,0);

	memset(&key,0,sizeof(DBT));
	memset(&value,0,sizeof(DBT));

	while((ret = svn_bdb_dbc_get(cursor,&key,&value,DB_NEXT)) == 0){
		memcpy((char *)cfile+4,value.data,value.size);

		if (cfile->project == id)
			svn_bdb_dbc_del(cursor,0);

		memset(&key,0,sizeof(DBT));
		memset(&value,0,sizeof(DBT));

	}


	if (cursor)
	{
		svn_bdb_dbc_close(cursor);
	}

	return SVN_NO_ERROR;
}